//
// 现已有写好的代码，因此不重复造了
// 代码改自《OpenCV4快速入门》 myRect.cpp
// 仅用作桂林电子科技大学2023赛季Evolution战队视觉组培训使用
//
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

int main() {
    cv::Mat img = cv::imread("../part7-2.JPG");
    if (img.empty()) {
        return -1;
    }
    cv::Mat img1, img2;
    img.copyTo(img1);  //深拷贝用来绘制最大外接矩形
    img.copyTo(img2);  //深拷贝用来绘制最小外接矩形
    imshow("img", img);

    //Canny边缘检测 去噪声与二值化
    cv::Mat canny;
    cv::Canny(img, canny, 80, 160, 3, false);
    cv::imshow("Canny", canny);

    //膨胀运算，将细小缝隙填补上
    cv::Mat kernel = getStructuringElement(0, cv::Size(3, 3));
    cv::dilate(canny, canny, kernel);

    //轮廓发现与绘制
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
    cv::findContours(canny, contours, hierarchy, 0, 2, cv::Point());

    //寻找轮廓的外接矩形
    for (int n = 0; n < contours.size(); n++) {
        cv::drawContours(canny, contours, n, cv::Scalar(255, 255, 255), 2, 8);//绘制轮廓

        double area = cv::contourArea(contours[n]);     //轮廓面积
        std::cout << "contour-" << n << " area=" << area << std::endl;

        double length = cv::arcLength(contours[n], true);       //轮廓长度
        std::cout << "contour-" << n << " length=" << length << std::endl;

        // 最大外接矩形
        cv::Rect rect = boundingRect(contours[n]);
        cv::rectangle(img1, rect, cv::Scalar(0, 0, 255), 2, 8, 0);
        cv::Point2i mcenter = cv::Point2i(rect.x + rect.width / 2, rect.y + rect.height / 2);  //最大外接矩形的中心
        cv::circle(img1, mcenter, 2, cv::Scalar(255, 0, 0), 2, 8, 0);
        cv::putText(img1, "contour-" + std::to_string(n), mcenter, 1, 1, cv::Scalar(0, 255, 0));

        // 最小外接矩形
        cv::RotatedRect rrect = minAreaRect(contours[n]);
        cv::Point2f points[4];
        rrect.points(points);  //读取最小外接矩形的四个顶点
        cv::Point2f ncenter = rrect.center;  //最小外接矩形的中心
        // 绘制旋转矩形与中心位置
        for (int i = 0; i < 4; i++) {
            if (i == 3) {
                cv::line(img2, points[i], points[0], cv::Scalar(0, 255, 0), 2, 8, 0);
                break;
            }
            cv::line(img2, points[i], points[i + 1], cv::Scalar(0, 255, 0), 2, 8, 0);
        }
        //绘制矩形的中心
        cv::circle(img2, ncenter, 2, cv::Scalar(255, 0, 0), 2, 8, 0);
        cv::putText(img2, "contour-" + std::to_string(n), rrect.center, 1, 1, cv::Scalar(0, 255, 0));
    }

    //输出绘制外接矩形的结果
    imshow("max", img1);
    imshow("min", img2);
    cv::waitKey(0);
    return 0;
}